/**
 * Copyright 2018 jianggujin (www.jianggujin.com).
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *      http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.jianggujin.modulelink.mvc.resolver;

import java.io.IOException;

import com.jianggujin.modulelink.mvc.JActionContext;
import com.jianggujin.modulelink.mvc.util.JWebUtils;
import com.jianggujin.modulelink.util.JAssert;

/**
 * 请求解析器管理
 * 
 * @author jianggujin
 *
 */
public class JRequestResolverManager {
   private static JRequestResolver jsonResolver = null;
   private static JRequestResolver xmlResolver = null;
   static {
      tryJsonResolverImplementation(new Runnable() {
         @Override
         public void run() {
            useJacksonJsonResolver();
         }
      });
      tryJsonResolverImplementation(new Runnable() {
         @Override
         public void run() {
            useFastjsonJsonResolver();
         }
      });
      tryXmlResolverImplementation(new Runnable() {
         @Override
         public void run() {
            useJacksonXmlResolver();
         }
      });
      tryXmlResolverImplementation(new Runnable() {
         @Override
         public void run() {
            useXStreamXmlResolver();
         }
      });
      tryXmlResolverImplementation(new Runnable() {
         @Override
         public void run() {
            useJAXBXmlResolver();
         }
      });
   }

   public static <T> T getBeanFromBodyWithJson(Class<T> clazz, JActionContext context) throws IOException {
      return getBeanFromBodyWithJson(clazz, context, JWebUtils.getRequestEncoding(context.getRequest()));
   }

   public static <T> T getBeanFromBodyWithJson(Class<T> clazz, JActionContext context, String charset) {
      JAssert.checkState(jsonResolver != null, "not found json resoler implementation");
      return jsonResolver.resolve(clazz, context, charset);
   }

   public static <T> T getBeanFromBodyWithXml(Class<T> clazz, JActionContext context) throws IOException {
      return getBeanFromBodyWithXml(clazz, context, JWebUtils.getRequestEncoding(context.getRequest()));
   }

   public static <T> T getBeanFromBodyWithXml(Class<T> clazz, JActionContext context, String charset) {
      JAssert.checkState(xmlResolver != null, "not found xml resoler implementation");
      return xmlResolver.resolve(clazz, context, charset);
   }

   public static void useJsonResolver(JRequestResolver resolver) {
      JRequestResolverManager.jsonResolver = resolver;
   }

   public static void useXmlResolver(JRequestResolver resolver) {
      JRequestResolverManager.xmlResolver = resolver;
   }

   public static synchronized void useJacksonXmlResolver() {
      JRequestResolverManager.xmlResolver = new com.jianggujin.modulelink.mvc.resolver.impl.JJacksonXmlRequestResolver();
   }

   public static synchronized void useJAXBXmlResolver() {
      JRequestResolverManager.xmlResolver = new com.jianggujin.modulelink.mvc.resolver.impl.JJAXBXmlRequestResolver();
   }

   public static synchronized void useXStreamXmlResolver() {
      JRequestResolverManager.xmlResolver = new com.jianggujin.modulelink.mvc.resolver.impl.JXStreamXmlRequestResolver();
   }

   public static synchronized void useJacksonJsonResolver() {
      JRequestResolverManager.jsonResolver = new com.jianggujin.modulelink.mvc.resolver.impl.JJacksonJsonRequestResolver();
   }

   public static synchronized void useFastjsonJsonResolver() {
      JRequestResolverManager.jsonResolver = new com.jianggujin.modulelink.mvc.resolver.impl.JFastjsonJsonRequestResolver();
   }

   private static void tryJsonResolverImplementation(Runnable runnable) {
      if (jsonResolver == null) {
         try {
            runnable.run();
         } catch (Throwable t) {
            // ignore
         }
      }
   }

   private static void tryXmlResolverImplementation(Runnable runnable) {
      if (xmlResolver == null) {
         try {
            runnable.run();
         } catch (Throwable t) {
            // ignore
         }
      }
   }
}
